import glm
import OpenGL.GL as gl
import numpy as np
import pygl

class VolumeCube:
    def __init__(self, volume:np.ndarray) -> None:
        vertices = np.array([
            -0.5,-0.5,-0.5,
             0.5,-0.5,-0.5,
             0.5, 0.5,-0.5,
            -0.5, 0.5,-0.5,
            -0.5,-0.5, 0.5,
             0.5,-0.5, 0.5,
             0.5, 0.5, 0.5,
            -0.5, 0.5, 0.5
        ], dtype=gl.GLfloat)
        indices = np.array([
            0, 5, 4,
            5, 0, 1,
            3, 7, 6,
            3, 6, 2,
            7, 4, 6,
            6, 4, 5,
            2, 1, 3,
            3, 1, 0,
            3, 0, 7,
            7, 0, 4,
            6, 5, 2,
            2, 5, 1 
        ], dtype=gl.GLuint)
        self.vao = pygl.VertexArrayObject()
        self.vbo = pygl.VertexBufferObject(vertices)
        self.ebo = pygl.ElementBufferObject(indices)
        binding_point = 0
        self.vao.setVertexBuffer(self.vbo, binding_point, 0, 
                                 3 * gl.sizeof(gl.GLfloat))
        self.vao.setElementBuffer(self.ebo)
        attribute_position = pygl.VertexAttribute("position", 0, 
                                                  3, gl.GL_FLOAT, False, 0)
        self.vao.setVertexAttribute(binding_point, attribute_position)
        self.tex = pygl.VolumeTexture3D(volume)
        self.rotation = glm.vec3(0.0, 0.0, 0.0)
        self.position = glm.vec3(0.0, 0.0, 0.0)
        self.scale = glm.vec3(1.0, 1.0, 1.0)
        self.updateModelMatrix()

    def render(self) -> None:
        self.vao.bind()
        self.tex.bind(0)
        gl.glDrawElements(gl.GL_TRIANGLES,36, gl.GL_UNSIGNED_INT, None)

    def delete(self)->None:
        self.vao.delete()
        self.vbo.delete()
        self.ebo.delete()
        self.tex.delete()

    def updateModelMatrix(self)->None:
        scale_matrix = glm.scale(glm.mat4(1.0), self.scale)
        rotation_matrix = glm.rotate(glm.mat4(1.0), glm.radians(self.rotation.x), 
                                     glm.vec3(1.0, 0.0, 0.0))
        rotation_matrix = glm.rotate(rotation_matrix, 
                        glm.radians(self.rotation.y), glm.vec3(0.0, 1.0, 0.0))
        rotation_matrix = glm.rotate(rotation_matrix, 
                        glm.radians(self.rotation.z), glm.vec3(0.0, 0.0, 1.0))
        translation_matrix = glm.translate(glm.mat4(1.0), self.position)
        self.model_matrix = translation_matrix * rotation_matrix * scale_matrix

